1. Project Clover database Tue Apr 9 2024 12:11:48 CDT
  2. Package com.alibaba.fastjson.serializer

File SerializeWriter.java

 

Coverage histogram

../../../../img/srcFileCovDistChart7.png
37% of files have more coverage

Code metrics

624
1,422
75
1
2,525
2,080
555
0.39
18.96
75
7.4

Classes

Class Line # Actions
SerializeWriter 36 1,422 0% 555 782
0.63130663.1%
 

Contributing tests

This file is covered by 2178 tests. .

Source view

1    /*
2    * Copyright 1999-2018 Alibaba Group.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10    * Unless required by applicable law or agreed to in writing, software
11    * distributed under the License is distributed on an "AS IS" BASIS,
12    * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13    * See the License for the specific language governing permissions and
14    * limitations under the License.
15    */
16    package com.alibaba.fastjson.serializer;
17   
18    import com.alibaba.fastjson.JSON;
19    import com.alibaba.fastjson.JSONException;
20    import com.alibaba.fastjson.util.IOUtils;
21    import com.alibaba.fastjson.util.RyuDouble;
22    import com.alibaba.fastjson.util.RyuFloat;
23   
24    import java.io.IOException;
25    import java.io.OutputStream;
26    import java.io.Writer;
27    import java.math.BigDecimal;
28    import java.nio.charset.Charset;
29    import java.util.List;
30   
31    import static com.alibaba.fastjson.util.IOUtils.replaceChars;
32   
33    /**
34    * @author wenshao[szujobs@hotmail.com]
35    */
 
36    public final class SerializeWriter extends Writer {
37    private final static ThreadLocal<char[]> bufLocal = new ThreadLocal<char[]>();
38    private final static ThreadLocal<byte[]> bytesBufLocal = new ThreadLocal<byte[]>();
39    private static int BUFFER_THRESHOLD = 1024 * 128;
40   
 
41  1 toggle static {
42  1 try {
43  1 String prop = IOUtils.getStringProperty("fastjson.serializer_buffer_threshold");
44  1 if (prop != null && prop.length() > 0) {
45  0 int serializer_buffer_threshold = Integer.parseInt(prop);
46  0 if (serializer_buffer_threshold >= 64 && serializer_buffer_threshold <= 1024 * 64) {
47  0 BUFFER_THRESHOLD = serializer_buffer_threshold * 1024;
48    }
49    }
50    } catch (Throwable error) {
51    // skip
52    }
53    }
54   
55    protected char buf[];
56   
57    /**
58    * The number of chars in the buffer.
59    */
60    protected int count;
61   
62    protected int features;
63   
64    private final Writer writer;
65   
66    protected boolean useSingleQuotes;
67    protected boolean quoteFieldNames;
68    protected boolean sortField;
69    protected boolean disableCircularReferenceDetect;
70    protected boolean beanToArray;
71    protected boolean writeNonStringValueAsString;
72    protected boolean notWriteDefaultValue;
73    protected boolean writeEnumUsingName;
74    protected boolean writeEnumUsingToString;
75    protected boolean writeDirect;
76   
77    protected char keySeperator;
78   
79    protected int maxBufSize = -1;
80   
81    protected boolean browserSecure;
82    protected long sepcialBits;
83   
 
84  465 toggle public SerializeWriter(){
85  465 this((Writer) null);
86    }
87   
 
88  492 toggle public SerializeWriter(Writer writer){
89  492 this(writer, JSON.DEFAULT_GENERATE_FEATURE, SerializerFeature.EMPTY);
90    }
91   
 
92  11 toggle public SerializeWriter(SerializerFeature... features){
93  11 this(null, features);
94    }
95   
 
96  11 toggle public SerializeWriter(Writer writer, SerializerFeature... features){
97  11 this(writer, 0, features);
98    }
99   
100    /**
101    * @since 1.2.9
102    * @param writer
103    * @param defaultFeatures
104    * @param features
105    */
 
106  19032735 toggle public SerializeWriter(Writer writer, int defaultFeatures, SerializerFeature... features){
107  19032735 this.writer = writer;
108   
109  19032734 buf = bufLocal.get();
110   
111  19032735 if (buf != null) {
112  19031431 bufLocal.set(null);
113    } else {
114  1304 buf = new char[2048];
115    }
116   
117  19032735 int featuresValue = defaultFeatures;
118  19032735 for (SerializerFeature feature : features) {
119  12002579 featuresValue |= feature.getMask();
120    }
121  19032733 this.features = featuresValue;
122   
123  19032732 computeFeatures();
124    }
125   
 
126  0 toggle public int getMaxBufSize() {
127  0 return maxBufSize;
128    }
129   
 
130  2 toggle public void setMaxBufSize(int maxBufSize) {
131  2 if (maxBufSize < this.buf.length) {
132  2 throw new JSONException("must > " + buf.length);
133    }
134   
135  0 this.maxBufSize = maxBufSize;
136    }
137   
 
138  23 toggle public int getBufferLength() {
139  23 return this.buf.length;
140    }
141   
 
142  74 toggle public SerializeWriter(int initialSize){
143  74 this(null, initialSize);
144    }
145   
 
146  105 toggle public SerializeWriter(Writer writer, int initialSize){
147  105 this.writer = writer;
148   
149  105 if (initialSize <= 0) {
150  1 throw new IllegalArgumentException("Negative initial size: " + initialSize);
151    }
152  104 buf = new char[initialSize];
153   
154  104 computeFeatures();
155    }
156   
 
157  163 toggle public void config(SerializerFeature feature, boolean state) {
158  163 if (state) {
159  134 features |= feature.getMask();
160    // 由于枚举序列化特性WriteEnumUsingToString和WriteEnumUsingName不能共存,需要检查
161  134 if (feature == SerializerFeature.WriteEnumUsingToString) {
162  3 features &= ~SerializerFeature.WriteEnumUsingName.getMask();
163  131 } else if (feature == SerializerFeature.WriteEnumUsingName) {
164  1 features &= ~SerializerFeature.WriteEnumUsingToString.getMask();
165    }
166    } else {
167  29 features &= ~feature.getMask();
168    }
169   
170  163 computeFeatures();
171    }
172   
173    final static int nonDirectFeatures = 0 //
174    | SerializerFeature.UseSingleQuotes.mask //
175    | SerializerFeature.BrowserCompatible.mask //
176    | SerializerFeature.PrettyFormat.mask //
177    | SerializerFeature.WriteEnumUsingToString.mask
178    | SerializerFeature.WriteNonStringValueAsString.mask
179    | SerializerFeature.WriteSlashAsSpecial.mask
180    | SerializerFeature.IgnoreErrorGetter.mask
181    | SerializerFeature.WriteClassName.mask
182    | SerializerFeature.NotWriteDefaultValue.mask
183    ;
 
184  19033000 toggle protected void computeFeatures() {
185  19033000 quoteFieldNames = (this.features & SerializerFeature.QuoteFieldNames.mask) != 0;
186  19033000 useSingleQuotes = (this.features & SerializerFeature.UseSingleQuotes.mask) != 0;
187  19033000 sortField = (this.features & SerializerFeature.SortField.mask) != 0;
188  19033000 disableCircularReferenceDetect = (this.features & SerializerFeature.DisableCircularReferenceDetect.mask) != 0;
189  19032999 beanToArray = (this.features & SerializerFeature.BeanToArray.mask) != 0;
190  19033000 writeNonStringValueAsString = (this.features & SerializerFeature.WriteNonStringValueAsString.mask) != 0;
191  19033000 notWriteDefaultValue = (this.features & SerializerFeature.NotWriteDefaultValue.mask) != 0;
192  19033000 writeEnumUsingName = (this.features & SerializerFeature.WriteEnumUsingName.mask) != 0;
193  19033000 writeEnumUsingToString = (this.features & SerializerFeature.WriteEnumUsingToString.mask) != 0;
194   
195  19033000 writeDirect = quoteFieldNames //
196    && (this.features & nonDirectFeatures) == 0 //
197    && (beanToArray || writeEnumUsingName)
198    ;
199   
200  19033000 keySeperator = useSingleQuotes ? '\'' : '"';
201   
202  19032999 browserSecure = (this.features & SerializerFeature.BrowserSecure.mask) != 0;
203   
204  19032999 final long S0 = 0x4FFFFFFFFL, S1 = 0x8004FFFFFFFFL, S2 = 0x50000304ffffffffL;
205    // long s = 0;
206    // for (int i = 0; i <= 31; ++i) {
207    // s |= (1L << i);
208    // }
209    // s |= (1L << '"');
210    //
211    // //S0 = s;
212    // //S1 = s | (1L << '/');
213    //
214    // s |= (1L << '('); // 41
215    // s |= (1L << ')'); // 42
216    // s |= (1L << '<'); // 60
217    // s |= (1L << '>'); // 62
218    // S2 = s;
219  19033000 sepcialBits = browserSecure
220    ? S2
221  19032830 : (features & SerializerFeature.WriteSlashAsSpecial.mask) != 0 ? S1 : S0;
222    }
223   
 
224  0 toggle public boolean isSortField() {
225  0 return sortField;
226    }
227   
 
228  18 toggle public boolean isNotWriteDefaultValue() {
229  18 return notWriteDefaultValue;
230    }
231   
 
232  115325730 toggle public boolean isEnabled(SerializerFeature feature) {
233  115325732 return (this.features & feature.mask) != 0;
234    }
235   
 
236  8785 toggle public boolean isEnabled(int feature) {
237  8785 return (this.features & feature) != 0;
238    }
239   
240    /**
241    * Writes a character to the buffer.
242    */
 
243  61137286 toggle public void write(int c) {
244  61137287 int newcount = count + 1;
245  61137287 if (newcount > buf.length) {
246  1040 if (writer == null) {
247  62 expandCapacity(newcount);
248    } else {
249  978 flush();
250  978 newcount = 1;
251    }
252    }
253  61137286 buf[count] = (char) c;
254  61137287 count = newcount;
255    }
256   
257    /**
258    * Writes characters to the buffer.
259    *
260    * @param c the data to be written
261    * @param off the start offset in the data
262    * @param len the number of chars that are written
263    */
 
264  3167164 toggle public void write(char c[], int off, int len) {
265  3167164 if (off < 0 //
266    || off > c.length //
267    || len < 0 //
268    || off + len > c.length //
269    || off + len < 0) {
270  10 throw new IndexOutOfBoundsException();
271  3167154 } else if (len == 0) {
272  1 return;
273    }
274   
275  3167153 int newcount = count + len;
276  3167152 if (newcount > buf.length) {
277  12722 if (writer == null) {
278  27 expandCapacity(newcount);
279    } else {
280  12695 do {
281  12723 int rest = buf.length - count;
282  12723 System.arraycopy(c, off, buf, count, rest);
283  12723 count = buf.length;
284  12723 flush();
285  12723 len -= rest;
286  12723 off += rest;
287  12723 } while (len > buf.length);
288  12695 newcount = len;
289    }
290    }
291  3167152 System.arraycopy(c, off, buf, count, len);
292  3167153 count = newcount;
293   
294    }
295   
 
296  340 toggle public void expandCapacity(int minimumCapacity) {
297  340 if (maxBufSize != -1 && minimumCapacity >= maxBufSize) {
298  0 throw new JSONException("serialize exceeded MAX_OUTPUT_LENGTH=" + maxBufSize + ", minimumCapacity=" + minimumCapacity);
299    }
300   
301  340 int newCapacity = buf.length + (buf.length >> 1) + 1;
302   
303  340 if (newCapacity < minimumCapacity) {
304  77 newCapacity = minimumCapacity;
305    }
306  340 char newValue[] = new char[newCapacity];
307  340 System.arraycopy(buf, 0, newValue, 0, count);
308   
309  340 if (buf.length < BUFFER_THRESHOLD) {
310  287 char[] charsLocal = bufLocal.get();
311  287 if (charsLocal == null || charsLocal.length < buf.length) {
312  175 bufLocal.set(buf);
313    }
314    }
315   
316  340 buf = newValue;
317    }
318   
 
319  11000462 toggle public SerializeWriter append(CharSequence csq) {
320  11000462 String s = (csq == null ? "null" : csq.toString());
321  11000462 write(s, 0, s.length());
322  11000462 return this;
323    }
324   
 
325  2 toggle public SerializeWriter append(CharSequence csq, int start, int end) {
326  2 String s = (csq == null ? "null" : csq).subSequence(start, end).toString();
327  2 write(s, 0, s.length());
328  2 return this;
329    }
330   
 
331  30479551 toggle public SerializeWriter append(char c) {
332  30479551 write(c);
333  30479552 return this;
334    }
335   
336    /**
337    * Write a portion of a string to the buffer.
338    *
339    * @param str String to be written from
340    * @param off Offset from which to start reading characters
341    * @param len Number of characters to be written
342    */
 
343  11015703 toggle public void write(String str, int off, int len) {
344  11015703 int newcount = count + len;
345  11015703 if (newcount > buf.length) {
346  91 if (writer == null) {
347  34 expandCapacity(newcount);
348    } else {
349  57 do {
350  114 int rest = buf.length - count;
351  114 str.getChars(off, off + rest, buf, count);
352  114 count = buf.length;
353  114 flush();
354  114 len -= rest;
355  114 off += rest;
356  114 } while (len > buf.length);
357  57 newcount = len;
358    }
359    }
360  11015703 str.getChars(off, off + len, buf, count);
361  11015703 count = newcount;
362    }
363   
364    /**
365    * Writes the contents of the buffer to another character stream.
366    *
367    * @param out the output stream to write to
368    * @throws IOException If an I/O error occurs.
369    */
 
370  13 toggle public void writeTo(Writer out) throws IOException {
371  13 if (this.writer != null) {
372  1 throw new UnsupportedOperationException("writer not null");
373    }
374  12 out.write(buf, 0, count);
375    }
376   
 
377  3 toggle public void writeTo(OutputStream out, String charsetName) throws IOException {
378  3 writeTo(out, Charset.forName(charsetName));
379    }
380   
 
381  4 toggle public void writeTo(OutputStream out, Charset charset) throws IOException {
382  4 writeToEx(out, charset);
383    }
384   
 
385  108 toggle public int writeToEx(OutputStream out, Charset charset) throws IOException {
386  108 if (this.writer != null) {
387  2 throw new UnsupportedOperationException("writer not null");
388    }
389   
390  106 if (charset == IOUtils.UTF8) {
391  100 return encodeToUTF8(out);
392    } else {
393  6 byte[] bytes = new String(buf, 0, count).getBytes(charset);
394  4 out.write(bytes);
395  4 return bytes.length;
396    }
397    }
398   
399    /**
400    * Returns a copy of the input data.
401    *
402    * @return an array of chars copied from the input data.
403    */
 
404  3 toggle public char[] toCharArray() {
405  3 if (this.writer != null) {
406  1 throw new UnsupportedOperationException("writer not null");
407    }
408   
409  2 char[] newValue = new char[count];
410  2 System.arraycopy(buf, 0, newValue, 0, count);
411  2 return newValue;
412    }
413   
414    /**
415    * only for springwebsocket
416    * @return
417    */
 
418  2 toggle public char[] toCharArrayForSpringWebSocket() {
419  2 if (this.writer != null) {
420  0 throw new UnsupportedOperationException("writer not null");
421    }
422   
423  2 char[] newValue = new char[count - 2];
424  2 System.arraycopy(buf, 1, newValue, 0, count - 2);
425  2 return newValue;
426    }
427   
 
428  12 toggle public byte[] toBytes(String charsetName) {
429  12 return toBytes(charsetName == null || "UTF-8".equals(charsetName) //
430    ? IOUtils.UTF8 //
431    : Charset.forName(charsetName));
432    }
433   
 
434  117 toggle public byte[] toBytes(Charset charset) {
435  117 if (this.writer != null) {
436  1 throw new UnsupportedOperationException("writer not null");
437    }
438   
439  116 if (charset == IOUtils.UTF8) {
440  112 return encodeToUTF8Bytes();
441    } else {
442  4 return new String(buf, 0, count).getBytes(charset);
443    }
444    }
445   
 
446  100 toggle private int encodeToUTF8(OutputStream out) throws IOException {
447   
448  100 int bytesLength = (int) (count * (double) 3);
449  100 byte[] bytes = bytesBufLocal.get();
450   
451  100 if (bytes == null) {
452  8 bytes = new byte[1024 * 8];
453  8 bytesBufLocal.set(bytes);
454    }
455   
456  100 if (bytes.length < bytesLength) {
457  0 bytes = new byte[bytesLength];
458    }
459   
460  100 int position = IOUtils.encodeUTF8(buf, 0, count, bytes);
461  100 out.write(bytes, 0, position);
462  94 return position;
463    }
464   
 
465  112 toggle private byte[] encodeToUTF8Bytes() {
466  112 int bytesLength = (int) (count * (double) 3);
467  112 byte[] bytes = bytesBufLocal.get();
468   
469  112 if (bytes == null) {
470  0 bytes = new byte[1024 * 8];
471  0 bytesBufLocal.set(bytes);
472    }
473   
474  112 if (bytes.length < bytesLength) {
475  1 bytes = new byte[bytesLength];
476    }
477   
478  112 int position = IOUtils.encodeUTF8(buf, 0, count, bytes);
479  112 byte[] copy = new byte[position];
480  112 System.arraycopy(bytes, 0, copy, 0, position);
481  112 return copy;
482    }
483   
 
484  2 toggle public int size() {
485  2 return count;
486    }
487   
 
488  19032464 toggle public String toString() {
489  19032464 return new String(buf, 0, count);
490    }
491   
492    /**
493    * Close the stream. This method does not release the buffer, since its contents might still be required. Note:
494    * Invoking this method in this class will have no effect.
495    */
 
496  19032505 toggle public void close() {
497  19032505 if (writer != null && count > 0) {
498  57 flush();
499    }
500  19032505 if (buf.length <= BUFFER_THRESHOLD) {
501  19032491 bufLocal.set(buf);
502    }
503   
504  19032505 this.buf = null;
505    }
506   
 
507  15220 toggle public void write(String text) {
508  15220 if (text == null) {
509  7 writeNull();
510  7 return;
511    }
512   
513  15213 write(text, 0, text.length());
514    }
515   
 
516  289017 toggle public void writeInt(int i) {
517  289014 if (i == Integer.MIN_VALUE) {
518  10 write("-2147483648");
519  10 return;
520    }
521   
522  289006 int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i);
523   
524  289009 int newcount = count + size;
525  289008 if (newcount > buf.length) {
526  4246 if (writer == null) {
527  27 expandCapacity(newcount);
528    } else {
529  4219 char[] chars = new char[size];
530  4219 IOUtils.getChars(i, size, chars);
531  4219 write(chars, 0, chars.length);
532  4219 return;
533    }
534    }
535   
536  284790 IOUtils.getChars(i, newcount, buf);
537   
538  284790 count = newcount;
539    }
540   
 
541  46 toggle public void writeByteArray(byte[] bytes) {
542  46 if (isEnabled(SerializerFeature.WriteClassName.mask)) {
543  2 writeHex(bytes);
544  2 return;
545    }
546   
547  44 int bytesLen = bytes.length;
548  43 final char quote = useSingleQuotes ? '\'' : '"';
549  44 if (bytesLen == 0) {
550  3 String emptyString = useSingleQuotes ? "''" : "\"\"";
551  3 write(emptyString);
552  3 return;
553    }
554   
555  41 final char[] CA = IOUtils.CA;
556   
557    // base64 algorithm author Mikael Grev
558  41 int eLen = (bytesLen / 3) * 3; // Length of even 24-bits.
559  41 int charsLen = ((bytesLen - 1) / 3 + 1) << 2; // base64 character count
560    // char[] chars = new char[charsLen];
561  41 int offset = count;
562  41 int newcount = count + charsLen + 2;
563  41 if (newcount > buf.length) {
564  2 if (writer != null) {
565  1 write(quote);
566   
567  5 for (int s = 0; s < eLen;) {
568    // Copy next three bytes into lower 24 bits of int, paying attension to sign.
569  4 int i = (bytes[s++] & 0xff) << 16 | (bytes[s++] & 0xff) << 8 | (bytes[s++] & 0xff);
570   
571    // Encode the int into four chars
572  4 write(CA[(i >>> 18) & 0x3f]);
573  4 write(CA[(i >>> 12) & 0x3f]);
574  4 write(CA[(i >>> 6) & 0x3f]);
575  4 write(CA[i & 0x3f]);
576    }
577   
578    // Pad and encode last bits if source isn't even 24 bits.
579  1 int left = bytesLen - eLen; // 0 - 2.
580  1 if (left > 0) {
581    // Prepare the int
582  1 int i = ((bytes[eLen] & 0xff) << 10) | (left == 2 ? ((bytes[bytesLen - 1] & 0xff) << 2) : 0);
583   
584    // Set last four chars
585  1 write(CA[i >> 12]);
586  1 write(CA[(i >>> 6) & 0x3f]);
587  1 write(left == 2 ? CA[i & 0x3f] : '=');
588  1 write('=');
589    }
590   
591  1 write(quote);
592  1 return;
593    }
594  1 expandCapacity(newcount);
595    }
596  40 count = newcount;
597  40 buf[offset++] = quote;
598   
599    // Encode even 24-bits
600  332 for (int s = 0, d = offset; s < eLen;) {
601    // Copy next three bytes into lower 24 bits of int, paying attension to sign.
602  292 int i = (bytes[s++] & 0xff) << 16 | (bytes[s++] & 0xff) << 8 | (bytes[s++] & 0xff);
603   
604    // Encode the int into four chars
605  292 buf[d++] = CA[(i >>> 18) & 0x3f];
606  292 buf[d++] = CA[(i >>> 12) & 0x3f];
607  292 buf[d++] = CA[(i >>> 6) & 0x3f];
608  292 buf[d++] = CA[i & 0x3f];
609    }
610   
611    // Pad and encode last bits if source isn't even 24 bits.
612  40 int left = bytesLen - eLen; // 0 - 2.
613  40 if (left > 0) {
614    // Prepare the int
615  25 int i = ((bytes[eLen] & 0xff) << 10) | (left == 2 ? ((bytes[bytesLen - 1] & 0xff) << 2) : 0);
616   
617    // Set last four chars
618  25 buf[newcount - 5] = CA[i >> 12];
619  25 buf[newcount - 4] = CA[(i >>> 6) & 0x3f];
620  25 buf[newcount - 3] = left == 2 ? CA[i & 0x3f] : '=';
621  25 buf[newcount - 2] = '=';
622    }
623  40 buf[newcount - 1] = quote;
624    }
625   
 
626  3 toggle public void writeHex(byte[] bytes) {
627  3 int newcount = count + bytes.length * 2 + 3;
628  3 if (newcount > buf.length) {
629  0 if (writer != null) {
630  0 char[] chars = new char[bytes.length * 2 + 3];
631  0 int pos = 0;
632  0 chars[pos++] = 'x';
633  0 chars[pos++] = '\'';
634   
635  0 for (int i = 0; i < bytes.length; ++i) {
636  0 byte b = bytes[i];
637   
638  0 int a = b & 0xFF;
639  0 int b0 = a >> 4;
640  0 int b1 = a & 0xf;
641   
642  0 chars[pos++] = (char) (b0 + (b0 < 10 ? 48 : 55));
643  0 chars[pos++] = (char) (b1 + (b1 < 10 ? 48 : 55));
644    }
645  0 chars[pos++] = '\'';
646  0 try {
647  0 writer.write(chars);
648    } catch (IOException ex) {
649  0 throw new JSONException("writeBytes error.", ex);
650    }
651  0 return;
652    }
653  0 expandCapacity(newcount);
654    }
655   
656  3 buf[count++] = 'x';
657  3 buf[count++] = '\'';
658   
659  25 for (int i = 0; i < bytes.length; ++i) {
660  22 byte b = bytes[i];
661   
662  22 int a = b & 0xFF;
663  22 int b0 = a >> 4;
664  22 int b1 = a & 0xf;
665   
666  22 buf[count++] = (char) (b0 + (b0 < 10 ? 48 : 55));
667  22 buf[count++] = (char) (b1 + (b1 < 10 ? 48 : 55));
668    }
669  3 buf[count++] = '\'';
670    }
671   
 
672  4000062 toggle public void writeFloat(float value, boolean checkWriteClassName) {
673  4000062 if (value != value || value == Float.POSITIVE_INFINITY || value == Float.NEGATIVE_INFINITY) {
674  11 writeNull();
675    } else {
676  4000051 int newcount = count + 15;
677  4000051 if (newcount > buf.length) {
678  1 if (writer == null) {
679  1 expandCapacity(newcount);
680    } else {
681  0 String str = RyuFloat.toString(value);
682  0 write(str, 0, str.length());
683   
684  0 if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) {
685  0 write('F');
686    }
687  0 return;
688    }
689    }
690   
691  4000051 int len = RyuFloat.toString(value, buf, count);
692  4000051 count += len;
693   
694  4000051 if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) {
695  3 write('F');
696    }
697    }
698    }
699   
 
700  4000081 toggle public void writeDouble(double value, boolean checkWriteClassName) {
701  4000081 if (Double.isNaN(value)
702    || Double.isInfinite(value)) {
703  0 writeNull();
704  0 return;
705    }
706   
707  4000081 int newcount = count + 24;
708  4000081 if (newcount > buf.length) {
709  1 if (writer == null) {
710  1 expandCapacity(newcount);
711    } else {
712  0 String str = RyuDouble.toString(value);
713  0 write(str, 0, str.length());
714   
715  0 if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) {
716  0 write('D');
717    }
718  0 return;
719    }
720    }
721   
722  4000081 int len = RyuDouble.toString(value, buf, count);
723  4000081 count += len;
724   
725  4000081 if (checkWriteClassName && isEnabled(SerializerFeature.WriteClassName)) {
726  2 write('D');
727    }
728    }
729   
 
730  12390 toggle public void writeEnum(Enum<?> value) {
731  12390 if (value == null) {
732  4100 writeNull();
733  4100 return;
734    }
735   
736  8290 String strVal = null;
737  8290 if (writeEnumUsingName && !writeEnumUsingToString) {
738  8259 strVal = value.name();
739  31 } else if (writeEnumUsingToString) {
740  25 strVal = value.toString();;
741    }
742   
743  8290 if (strVal != null) {
744  8284 char quote = isEnabled(SerializerFeature.UseSingleQuotes) ? '\'' : '"';
745  8284 write(quote);
746  8284 write(strVal);
747  8284 write(quote);
748    } else {
749  6 writeInt(value.ordinal());
750    }
751    }
752   
753    /**
754    * @deprecated
755    */
 
756  0 toggle public void writeLongAndChar(long i, char c) throws IOException {
757  0 writeLong(i);
758  0 write(c);
759    }
760   
 
761  51833 toggle public void writeLong(long i) {
762  51833 boolean needQuotationMark = isEnabled(SerializerFeature.BrowserCompatible) //
763    && (!isEnabled(SerializerFeature.WriteClassName)) //
764    && (i > 9007199254740991L || i < -9007199254740991L);
765   
766  51833 if (i == Long.MIN_VALUE) {
767  27 if (needQuotationMark) {
768  5 write("\"-9223372036854775808\"");
769    } else {
770  22 write("-9223372036854775808");
771    }
772  27 return;
773    }
774   
775  51806 int size = (i < 0) ? IOUtils.stringSize(-i) + 1 : IOUtils.stringSize(i);
776   
777  51806 int newcount = count + size;
778  2052 if (needQuotationMark) newcount += 2;
779  51806 if (newcount > buf.length) {
780  38 if (writer == null) {
781  29 expandCapacity(newcount);
782    } else {
783  9 char[] chars = new char[size];
784  9 IOUtils.getChars(i, size, chars);
785  9 if (needQuotationMark) {
786  5 write('"');
787  5 write(chars, 0, chars.length);
788  5 write('"');
789    } else {
790  4 write(chars, 0, chars.length);
791    }
792  9 return;
793    }
794    }
795   
796  51797 if (needQuotationMark) {
797  2047 buf[count] = '"';
798  2047 IOUtils.getChars(i, newcount - 1, buf);
799  2047 buf[newcount - 1] = '"';
800    } else {
801  49750 IOUtils.getChars(i, newcount, buf);
802    }
803   
804  51797 count = newcount;
805    }
806   
 
807  4390 toggle public void writeNull() {
808  4390 write("null");
809    }
810   
 
811  51 toggle public void writeNull(SerializerFeature feature) {
812  51 writeNull(0, feature.mask);
813    }
814   
 
815  99 toggle public void writeNull(int beanFeatures , int feature) {
816  99 if ((beanFeatures & feature) == 0 //
817    && (this.features & feature) == 0) {
818  73 writeNull();
819  73 return;
820    }
821   
822  26 if (feature == SerializerFeature.WriteNullListAsEmpty.mask) {
823  22 write("[]");
824  4 } else if (feature == SerializerFeature.WriteNullStringAsEmpty.mask) {
825  4 writeString("");
826  0 } else if (feature == SerializerFeature.WriteNullBooleanAsFalse.mask) {
827  0 write("false");
828  0 } else if (feature == SerializerFeature.WriteNullNumberAsZero.mask) {
829  0 write('0');
830    } else {
831  0 writeNull();
832    }
833    }
834   
 
835  4084565 toggle public void writeStringWithDoubleQuote(String text, final char seperator) {
836  4084565 if (text == null) {
837  1 writeNull();
838  1 if (seperator != 0) {
839  0 write(seperator);
840    }
841  1 return;
842    }
843   
844  4084564 int len = text.length();
845  4084564 int newcount = count + len + 2;
846  4084564 if (seperator != 0) {
847  4012279 newcount++;
848    }
849   
850  4084564 if (newcount > buf.length) {
851  111 if (writer != null) {
852  18 write('"');
853   
854  204735 for (int i = 0; i < text.length(); ++i) {
855  204717 char ch = text.charAt(i);
856   
857  204717 if (isEnabled(SerializerFeature.BrowserSecure)) {
858  73535 if (ch == '(' || ch == ')' || ch == '<' || ch == '>') {
859  2004 write('\\');
860  2004 write('u');
861  2004 write(IOUtils.DIGITS[(ch >>> 12) & 15]);
862  2004 write(IOUtils.DIGITS[(ch >>> 8 ) & 15]);
863  2004 write(IOUtils.DIGITS[(ch >>> 4 ) & 15]);
864  2004 write(IOUtils.DIGITS[ch & 15]);
865  2004 continue;
866    }
867    }
868   
869  202713 if (isEnabled(SerializerFeature.BrowserCompatible)) {
870  65549 if (ch == '\b' //
871    || ch == '\f' //
872    || ch == '\n' //
873    || ch == '\r' //
874    || ch == '\t' //
875    || ch == '"' //
876    || ch == '/' //
877    || ch == '\\') {
878  9 write('\\');
879  9 write(replaceChars[(int) ch]);
880  9 continue;
881    }
882   
883  65540 if (ch < 32) {
884  27 write('\\');
885  27 write('u');
886  27 write('0');
887  27 write('0');
888  27 write(IOUtils.ASCII_CHARS[ch * 2 ]);
889  27 write(IOUtils.ASCII_CHARS[ch * 2 + 1]);
890  27 continue;
891    }
892   
893  65513 if (ch >= 127) {
894  65408 write('\\');
895  65408 write('u');
896  65408 write(IOUtils.DIGITS[(ch >>> 12) & 15]);
897  65408 write(IOUtils.DIGITS[(ch >>> 8 ) & 15]);
898  65408 write(IOUtils.DIGITS[(ch >>> 4 ) & 15]);
899  65408 write(IOUtils.DIGITS[ ch & 15]);
900  65408 continue;
901    }
902    } else {
903  137164 if (ch < IOUtils.specicalFlags_doubleQuotes.length
904    && IOUtils.specicalFlags_doubleQuotes[ch] != 0 //
905    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
906  137 write('\\');
907  137 if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
908  120 write('u');
909  120 write(IOUtils.DIGITS[ch >>> 12 & 15]);
910  120 write(IOUtils.DIGITS[ch >>> 8 & 15]);
911  120 write(IOUtils.DIGITS[ch >>> 4 & 15]);
912  120 write(IOUtils.DIGITS[ch & 15]);
913    } else {
914  17 write(IOUtils.replaceChars[ch]);
915    }
916  137 continue;
917    }
918    }
919   
920  137132 write(ch);
921    }
922   
923  18 write('"');
924  18 if (seperator != 0) {
925  5 write(seperator);
926    }
927  18 return;
928    }
929  93 expandCapacity(newcount);
930    }
931   
932  4084546 int start = count + 1;
933  4084546 int end = start + len;
934   
935  4084546 buf[count] = '\"';
936  4084546 text.getChars(0, len, buf, start);
937   
938  4084546 count = newcount;
939   
940  4084546 if (isEnabled(SerializerFeature.BrowserCompatible)) {
941  10107 int lastSpecialIndex = -1;
942   
943  1143516 for (int i = start; i < end; ++i) {
944  1133409 char ch = buf[i];
945   
946  1133409 if (ch == '"' //
947    || ch == '/' //
948    || ch == '\\') {
949  11695 lastSpecialIndex = i;
950  11695 newcount += 1;
951  11695 continue;
952    }
953   
954  1121714 if (ch == '\b' //
955    || ch == '\f' //
956    || ch == '\n' //
957    || ch == '\r' //
958    || ch == '\t') {
959  19561 lastSpecialIndex = i;
960  19561 newcount += 1;
961  19561 continue;
962    }
963   
964  1102153 if (ch < 32) {
965  105445 lastSpecialIndex = i;
966  105445 newcount += 5;
967  105445 continue;
968    }
969   
970  996708 if (ch >= 127) {
971  635233 lastSpecialIndex = i;
972  635233 newcount += 5;
973  635233 continue;
974    }
975    }
976   
977  10107 if (newcount > buf.length) {
978  8 expandCapacity(newcount);
979    }
980  10107 count = newcount;
981   
982  1137754 for (int i = lastSpecialIndex; i >= start; --i) {
983  1127647 char ch = buf[i];
984   
985  1127647 if (ch == '\b' //
986    || ch == '\f'//
987    || ch == '\n' //
988    || ch == '\r' //
989    || ch == '\t'
990    ) {
991  19561 System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1);
992  19561 buf[i] = '\\';
993  19561 buf[i + 1] = replaceChars[(int) ch];
994  19561 end += 1;
995  19561 continue;
996    }
997   
998  1108086 if (ch == '"' //
999    || ch == '/' //
1000    || ch == '\\'
1001    ) {
1002  11695 System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1);
1003  11695 buf[i] = '\\';
1004  11695 buf[i + 1] = ch;
1005  11695 end += 1;
1006  11695 continue;
1007    }
1008   
1009  1096391 if (ch < 32) {
1010  105445 System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1);
1011  105445 buf[i ] = '\\';
1012  105445 buf[i + 1] = 'u';
1013  105445 buf[i + 2] = '0';
1014  105445 buf[i + 3] = '0';
1015  105445 buf[i + 4] = IOUtils.ASCII_CHARS[ch * 2];
1016  105445 buf[i + 5] = IOUtils.ASCII_CHARS[ch * 2 + 1];
1017  105445 end += 5;
1018  105445 continue;
1019    }
1020   
1021  990946 if (ch >= 127) {
1022  635233 System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1);
1023  635233 buf[i ] = '\\';
1024  635233 buf[i + 1] = 'u';
1025  635233 buf[i + 2] = IOUtils.DIGITS[(ch >>> 12) & 15];
1026  635233 buf[i + 3] = IOUtils.DIGITS[(ch >>> 8) & 15];
1027  635233 buf[i + 4] = IOUtils.DIGITS[(ch >>> 4) & 15];
1028  635233 buf[i + 5] = IOUtils.DIGITS[ch & 15];
1029  635233 end += 5;
1030    }
1031    }
1032   
1033  10107 if (seperator != 0) {
1034  15 buf[count - 2] = '\"';
1035  15 buf[count - 1] = seperator;
1036    } else {
1037  10092 buf[count - 1] = '\"';
1038    }
1039   
1040  10107 return;
1041    }
1042   
1043  4074439 int specialCount = 0;
1044  4074439 int lastSpecialIndex = -1;
1045  4074439 int firstSpecialIndex = -1;
1046  4074439 char lastSpecial = '\0';
1047   
1048  21976126 for (int i = start; i < end; ++i) {
1049  17901687 char ch = buf[i];
1050   
1051  17901687 if (ch >= ']') { // 93
1052  16497192 if (ch >= 0x7F //
1053    && (ch == '\u2028' //
1054    || ch == '\u2029' //
1055    || ch < 0xA0)) {
1056  259963 if (firstSpecialIndex == -1) {
1057  11012 firstSpecialIndex = i;
1058    }
1059   
1060  259963 specialCount++;
1061  259963 lastSpecialIndex = i;
1062  259963 lastSpecial = ch;
1063  259963 newcount += 4;
1064    }
1065  16497192 continue;
1066    }
1067   
1068  1404495 boolean special = (ch < 64 && (sepcialBits & (1L << ch)) != 0) || ch == '\\';
1069  1404495 if (special) {
1070  288069 specialCount++;
1071  288069 lastSpecialIndex = i;
1072  288069 lastSpecial = ch;
1073   
1074  288069 if (ch == '('
1075    || ch == ')'
1076    || ch == '<'
1077    || ch == '>'
1078    || (ch < IOUtils.specicalFlags_doubleQuotes.length //
1079    && IOUtils.specicalFlags_doubleQuotes[ch] == 4) //
1080    ) {
1081  231289 newcount += 4;
1082    }
1083   
1084  288069 if (firstSpecialIndex == -1) {
1085  11894 firstSpecialIndex = i;
1086    }
1087    }
1088    }
1089   
1090  4074439 if (specialCount > 0) {
1091  22906 newcount += specialCount;
1092  22906 if (newcount > buf.length) {
1093  23 expandCapacity(newcount);
1094    }
1095  22906 count = newcount;
1096   
1097  22906 if (specialCount == 1) {
1098  2703 if (lastSpecial == '\u2028') {
1099  46 int srcPos = lastSpecialIndex + 1;
1100  46 int destPos = lastSpecialIndex + 6;
1101  46 int LengthOfCopy = end - lastSpecialIndex - 1;
1102   
1103  46 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1104  46 buf[lastSpecialIndex ] = '\\';
1105  46 buf[++lastSpecialIndex] = 'u';
1106  46 buf[++lastSpecialIndex] = '2';
1107  46 buf[++lastSpecialIndex] = '0';
1108  46 buf[++lastSpecialIndex] = '2';
1109  46 buf[++lastSpecialIndex] = '8';
1110   
1111  2657 } else if (lastSpecial == '\u2029') {
1112  38 int srcPos = lastSpecialIndex + 1;
1113  38 int destPos = lastSpecialIndex + 6;
1114  38 int LengthOfCopy = end - lastSpecialIndex - 1;
1115   
1116  38 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1117  38 buf[lastSpecialIndex ] = '\\';
1118  38 buf[++lastSpecialIndex] = 'u';
1119  38 buf[++lastSpecialIndex] = '2';
1120  38 buf[++lastSpecialIndex] = '0';
1121  38 buf[++lastSpecialIndex] = '2';
1122  38 buf[++lastSpecialIndex] = '9';
1123   
1124  2619 } else if (lastSpecial == '(' || lastSpecial == ')' || lastSpecial == '<' || lastSpecial == '>') {
1125  17 int srcPos = lastSpecialIndex + 1;
1126  17 int destPos = lastSpecialIndex + 6;
1127  17 int LengthOfCopy = end - lastSpecialIndex - 1;
1128  17 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1129  17 buf[lastSpecialIndex] = '\\';
1130  17 buf[++lastSpecialIndex] = 'u';
1131   
1132  17 final char ch = lastSpecial;
1133  17 buf[++lastSpecialIndex] = IOUtils.DIGITS[(ch >>> 12) & 15];
1134  17 buf[++lastSpecialIndex] = IOUtils.DIGITS[(ch >>> 8) & 15];
1135  17 buf[++lastSpecialIndex] = IOUtils.DIGITS[(ch >>> 4) & 15];
1136  17 buf[++lastSpecialIndex] = IOUtils.DIGITS[ch & 15];
1137    } else {
1138  2602 final char ch = lastSpecial;
1139  2602 if (ch < IOUtils.specicalFlags_doubleQuotes.length //
1140    && IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
1141  2299 int srcPos = lastSpecialIndex + 1;
1142  2299 int destPos = lastSpecialIndex + 6;
1143  2299 int LengthOfCopy = end - lastSpecialIndex - 1;
1144  2299 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1145   
1146  2299 int bufIndex = lastSpecialIndex;
1147  2299 buf[bufIndex++] = '\\';
1148  2299 buf[bufIndex++] = 'u';
1149  2299 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1150  2299 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
1151  2299 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
1152  2299 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1153    } else {
1154  303 int srcPos = lastSpecialIndex + 1;
1155  303 int destPos = lastSpecialIndex + 2;
1156  303 int LengthOfCopy = end - lastSpecialIndex - 1;
1157  303 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1158  303 buf[lastSpecialIndex] = '\\';
1159  303 buf[++lastSpecialIndex] = replaceChars[(int) ch];
1160    }
1161    }
1162  20203 } else if (specialCount > 1) {
1163  20203 int textIndex = firstSpecialIndex - start;
1164  20203 int bufIndex = firstSpecialIndex;
1165  2612059 for (int i = textIndex; i < text.length(); ++i) {
1166  2591856 char ch = text.charAt(i);
1167   
1168  2591856 if (browserSecure && (ch == '('
1169    || ch == ')'
1170    || ch == '<'
1171    || ch == '>')) {
1172  15703 buf[bufIndex++] = '\\';
1173  15703 buf[bufIndex++] = 'u';
1174  15703 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1175  15703 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15];
1176  15703 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15];
1177  15703 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1178  15703 end += 5;
1179  2576153 } else if (ch < IOUtils.specicalFlags_doubleQuotes.length //
1180    && IOUtils.specicalFlags_doubleQuotes[ch] != 0 //
1181    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
1182  528576 buf[bufIndex++] = '\\';
1183  528576 if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
1184  472099 buf[bufIndex++] = 'u';
1185  472099 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1186  472099 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15];
1187  472099 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15];
1188  472099 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1189  472099 end += 5;
1190    } else {
1191  56477 buf[bufIndex++] = replaceChars[(int) ch];
1192  56477 end++;
1193    }
1194    } else {
1195  2047577 if (ch == '\u2028' || ch == '\u2029') {
1196  1050 buf[bufIndex++] = '\\';
1197  1050 buf[bufIndex++] = 'u';
1198  1050 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1199  1050 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15];
1200  1050 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15];
1201  1050 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1202  1050 end += 5;
1203    } else {
1204  2046527 buf[bufIndex++] = ch;
1205    }
1206    }
1207    }
1208    }
1209    }
1210   
1211  4074439 if (seperator != 0) {
1212  4012259 buf[count - 2] = '\"';
1213  4012259 buf[count - 1] = seperator;
1214    } else {
1215  62180 buf[count - 1] = '\"';
1216    }
1217    }
1218   
 
1219  0 toggle public void writeStringWithDoubleQuote(char[] text, final char seperator) {
1220  0 if (text == null) {
1221  0 writeNull();
1222  0 if (seperator != 0) {
1223  0 write(seperator);
1224    }
1225  0 return;
1226    }
1227   
1228  0 int len = text.length;
1229  0 int newcount = count + len + 2;
1230  0 if (seperator != 0) {
1231  0 newcount++;
1232    }
1233   
1234  0 if (newcount > buf.length) {
1235  0 if (writer != null) {
1236  0 write('"');
1237   
1238  0 for (int i = 0; i < text.length; ++i) {
1239  0 char ch = text[i];
1240   
1241  0 if (isEnabled(SerializerFeature.BrowserSecure)) {
1242  0 if (ch == '('
1243    || ch == ')'
1244    || ch == '<'
1245    || ch == '>'
1246    ) {
1247  0 write('\\');
1248  0 write('u');
1249  0 write(IOUtils.DIGITS[(ch >>> 12) & 15]);
1250  0 write(IOUtils.DIGITS[(ch >>> 8 ) & 15]);
1251  0 write(IOUtils.DIGITS[(ch >>> 4 ) & 15]);
1252  0 write(IOUtils.DIGITS[ch & 15]);
1253  0 continue;
1254    }
1255    }
1256   
1257  0 if (isEnabled(SerializerFeature.BrowserCompatible)) {
1258  0 if (ch == '\b' //
1259    || ch == '\f' //
1260    || ch == '\n' //
1261    || ch == '\r' //
1262    || ch == '\t' //
1263    || ch == '"' //
1264    || ch == '/' //
1265    || ch == '\\') {
1266  0 write('\\');
1267  0 write(replaceChars[(int) ch]);
1268  0 continue;
1269    }
1270   
1271  0 if (ch < 32) {
1272  0 write('\\');
1273  0 write('u');
1274  0 write('0');
1275  0 write('0');
1276  0 write(IOUtils.ASCII_CHARS[ch * 2 ]);
1277  0 write(IOUtils.ASCII_CHARS[ch * 2 + 1]);
1278  0 continue;
1279    }
1280   
1281  0 if (ch >= 127) {
1282  0 write('\\');
1283  0 write('u');
1284  0 write(IOUtils.DIGITS[(ch >>> 12) & 15]);
1285  0 write(IOUtils.DIGITS[(ch >>> 8 ) & 15]);
1286  0 write(IOUtils.DIGITS[(ch >>> 4 ) & 15]);
1287  0 write(IOUtils.DIGITS[ch & 15]);
1288  0 continue;
1289    }
1290    } else {
1291  0 if (ch < IOUtils.specicalFlags_doubleQuotes.length
1292    && IOUtils.specicalFlags_doubleQuotes[ch] != 0 //
1293    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
1294  0 write('\\');
1295  0 if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
1296  0 write('u');
1297  0 write(IOUtils.DIGITS[ch >>> 12 & 15]);
1298  0 write(IOUtils.DIGITS[ch >>> 8 & 15]);
1299  0 write(IOUtils.DIGITS[ch >>> 4 & 15]);
1300  0 write(IOUtils.DIGITS[ch & 15]);
1301    } else {
1302  0 write(IOUtils.replaceChars[ch]);
1303    }
1304  0 continue;
1305    }
1306    }
1307   
1308  0 write(ch);
1309    }
1310   
1311  0 write('"');
1312  0 if (seperator != 0) {
1313  0 write(seperator);
1314    }
1315  0 return;
1316    }
1317  0 expandCapacity(newcount);
1318    }
1319   
1320  0 int start = count + 1;
1321  0 int end = start + len;
1322   
1323  0 buf[count] = '\"';
1324    // text.getChars(0, len, buf, start);
1325  0 System.arraycopy(text, 0, buf, start, text.length);
1326   
1327  0 count = newcount;
1328   
1329  0 if (isEnabled(SerializerFeature.BrowserCompatible)) {
1330  0 int lastSpecialIndex = -1;
1331   
1332  0 for (int i = start; i < end; ++i) {
1333  0 char ch = buf[i];
1334   
1335  0 if (ch == '"' //
1336    || ch == '/' //
1337    || ch == '\\') {
1338  0 lastSpecialIndex = i;
1339  0 newcount += 1;
1340  0 continue;
1341    }
1342   
1343  0 if (ch == '\b' //
1344    || ch == '\f' //
1345    || ch == '\n' //
1346    || ch == '\r' //
1347    || ch == '\t') {
1348  0 lastSpecialIndex = i;
1349  0 newcount += 1;
1350  0 continue;
1351    }
1352   
1353  0 if (ch < 32) {
1354  0 lastSpecialIndex = i;
1355  0 newcount += 5;
1356  0 continue;
1357    }
1358   
1359  0 if (ch >= 127) {
1360  0 lastSpecialIndex = i;
1361  0 newcount += 5;
1362  0 continue;
1363    }
1364    }
1365   
1366  0 if (newcount > buf.length) {
1367  0 expandCapacity(newcount);
1368    }
1369  0 count = newcount;
1370   
1371  0 for (int i = lastSpecialIndex; i >= start; --i) {
1372  0 char ch = buf[i];
1373   
1374  0 if (ch == '\b' //
1375    || ch == '\f'//
1376    || ch == '\n' //
1377    || ch == '\r' //
1378    || ch == '\t') {
1379  0 System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1);
1380  0 buf[i] = '\\';
1381  0 buf[i + 1] = replaceChars[(int) ch];
1382  0 end += 1;
1383  0 continue;
1384    }
1385   
1386  0 if (ch == '"' //
1387    || ch == '/' //
1388    || ch == '\\') {
1389  0 System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1);
1390  0 buf[i] = '\\';
1391  0 buf[i + 1] = ch;
1392  0 end += 1;
1393  0 continue;
1394    }
1395   
1396  0 if (ch < 32) {
1397  0 System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1);
1398  0 buf[i] = '\\';
1399  0 buf[i + 1] = 'u';
1400  0 buf[i + 2] = '0';
1401  0 buf[i + 3] = '0';
1402  0 buf[i + 4] = IOUtils.ASCII_CHARS[ch * 2];
1403  0 buf[i + 5] = IOUtils.ASCII_CHARS[ch * 2 + 1];
1404  0 end += 5;
1405  0 continue;
1406    }
1407   
1408  0 if (ch >= 127) {
1409  0 System.arraycopy(buf, i + 1, buf, i + 6, end - i - 1);
1410  0 buf[i] = '\\';
1411  0 buf[i + 1] = 'u';
1412  0 buf[i + 2] = IOUtils.DIGITS[(ch >>> 12) & 15];
1413  0 buf[i + 3] = IOUtils.DIGITS[(ch >>> 8) & 15];
1414  0 buf[i + 4] = IOUtils.DIGITS[(ch >>> 4) & 15];
1415  0 buf[i + 5] = IOUtils.DIGITS[ch & 15];
1416  0 end += 5;
1417    }
1418    }
1419   
1420  0 if (seperator != 0) {
1421  0 buf[count - 2] = '\"';
1422  0 buf[count - 1] = seperator;
1423    } else {
1424  0 buf[count - 1] = '\"';
1425    }
1426   
1427  0 return;
1428    }
1429   
1430  0 int specialCount = 0;
1431  0 int lastSpecialIndex = -1;
1432  0 int firstSpecialIndex = -1;
1433  0 char lastSpecial = '\0';
1434   
1435  0 for (int i = start; i < end; ++i) {
1436  0 char ch = buf[i];
1437   
1438  0 if (ch >= ']') { // 93
1439  0 if (ch >= 0x7F //
1440    && (ch == '\u2028' //
1441    || ch == '\u2029' //
1442    || ch < 0xA0)) {
1443  0 if (firstSpecialIndex == -1) {
1444  0 firstSpecialIndex = i;
1445    }
1446   
1447  0 specialCount++;
1448  0 lastSpecialIndex = i;
1449  0 lastSpecial = ch;
1450  0 newcount += 4;
1451    }
1452  0 continue;
1453    }
1454   
1455  0 boolean special = (ch < 64 && (sepcialBits & (1L << ch)) != 0) || ch == '\\';
1456  0 if (special) {
1457  0 specialCount++;
1458  0 lastSpecialIndex = i;
1459  0 lastSpecial = ch;
1460   
1461  0 if (ch == '('
1462    || ch == ')'
1463    || ch == '<'
1464    || ch == '>'
1465    || (ch < IOUtils.specicalFlags_doubleQuotes.length //
1466    && IOUtils.specicalFlags_doubleQuotes[ch] == 4) //
1467    ) {
1468  0 newcount += 4;
1469    }
1470   
1471  0 if (firstSpecialIndex == -1) {
1472  0 firstSpecialIndex = i;
1473    }
1474    }
1475    }
1476   
1477  0 if (specialCount > 0) {
1478  0 newcount += specialCount;
1479  0 if (newcount > buf.length) {
1480  0 expandCapacity(newcount);
1481    }
1482  0 count = newcount;
1483   
1484  0 if (specialCount == 1) {
1485  0 if (lastSpecial == '\u2028') {
1486  0 int srcPos = lastSpecialIndex + 1;
1487  0 int destPos = lastSpecialIndex + 6;
1488  0 int LengthOfCopy = end - lastSpecialIndex - 1;
1489  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1490  0 buf[lastSpecialIndex ] = '\\';
1491  0 buf[++lastSpecialIndex] = 'u';
1492  0 buf[++lastSpecialIndex] = '2';
1493  0 buf[++lastSpecialIndex] = '0';
1494  0 buf[++lastSpecialIndex] = '2';
1495  0 buf[++lastSpecialIndex] = '8';
1496  0 } else if (lastSpecial == '\u2029') {
1497  0 int srcPos = lastSpecialIndex + 1;
1498  0 int destPos = lastSpecialIndex + 6;
1499  0 int LengthOfCopy = end - lastSpecialIndex - 1;
1500  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1501  0 buf[lastSpecialIndex ] = '\\';
1502  0 buf[++lastSpecialIndex] = 'u';
1503  0 buf[++lastSpecialIndex] = '2';
1504  0 buf[++lastSpecialIndex] = '0';
1505  0 buf[++lastSpecialIndex] = '2';
1506  0 buf[++lastSpecialIndex] = '9';
1507  0 } else if (lastSpecial == '(' || lastSpecial == ')' || lastSpecial == '<' || lastSpecial == '>') {
1508  0 int srcPos = lastSpecialIndex + 1;
1509  0 int destPos = lastSpecialIndex + 6;
1510  0 int LengthOfCopy = end - lastSpecialIndex - 1;
1511  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1512  0 buf[lastSpecialIndex] = '\\';
1513  0 buf[++lastSpecialIndex] = 'u';
1514   
1515  0 final char ch = lastSpecial;
1516  0 buf[++lastSpecialIndex] = IOUtils.DIGITS[(ch >>> 12) & 15];
1517  0 buf[++lastSpecialIndex] = IOUtils.DIGITS[(ch >>> 8) & 15];
1518  0 buf[++lastSpecialIndex] = IOUtils.DIGITS[(ch >>> 4) & 15];
1519  0 buf[++lastSpecialIndex] = IOUtils.DIGITS[ch & 15];
1520    } else {
1521  0 final char ch = lastSpecial;
1522  0 if (ch < IOUtils.specicalFlags_doubleQuotes.length //
1523    && IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
1524  0 int srcPos = lastSpecialIndex + 1;
1525  0 int destPos = lastSpecialIndex + 6;
1526  0 int LengthOfCopy = end - lastSpecialIndex - 1;
1527  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1528   
1529  0 int bufIndex = lastSpecialIndex;
1530  0 buf[bufIndex++] = '\\';
1531  0 buf[bufIndex++] = 'u';
1532  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1533  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
1534  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
1535  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1536    } else {
1537  0 int srcPos = lastSpecialIndex + 1;
1538  0 int destPos = lastSpecialIndex + 2;
1539  0 int LengthOfCopy = end - lastSpecialIndex - 1;
1540  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1541  0 buf[lastSpecialIndex] = '\\';
1542  0 buf[++lastSpecialIndex] = replaceChars[(int) ch];
1543    }
1544    }
1545  0 } else if (specialCount > 1) {
1546  0 int textIndex = firstSpecialIndex - start;
1547  0 int bufIndex = firstSpecialIndex;
1548  0 for (int i = textIndex; i < text.length; ++i) {
1549  0 char ch = text[i];
1550   
1551  0 if (browserSecure && (ch == '('
1552    || ch == ')'
1553    || ch == '<'
1554    || ch == '>')) {
1555  0 buf[bufIndex++] = '\\';
1556  0 buf[bufIndex++] = 'u';
1557  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1558  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
1559  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
1560  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1561  0 end += 5;
1562  0 } else if (ch < IOUtils.specicalFlags_doubleQuotes.length //
1563    && IOUtils.specicalFlags_doubleQuotes[ch] != 0 //
1564    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
1565  0 buf[bufIndex++] = '\\';
1566  0 if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
1567  0 buf[bufIndex++] = 'u';
1568  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1569  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
1570  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
1571  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1572  0 end += 5;
1573    } else {
1574  0 buf[bufIndex++] = replaceChars[(int) ch];
1575  0 end++;
1576    }
1577    } else {
1578  0 if (ch == '\u2028' || ch == '\u2029') {
1579  0 buf[bufIndex++] = '\\';
1580  0 buf[bufIndex++] = 'u';
1581  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
1582  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
1583  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
1584  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
1585  0 end += 5;
1586    } else {
1587  0 buf[bufIndex++] = ch;
1588    }
1589    }
1590    }
1591    }
1592    }
1593   
1594  0 if (seperator != 0) {
1595  0 buf[count - 2] = '\"';
1596  0 buf[count - 1] = seperator;
1597    } else {
1598  0 buf[count - 1] = '\"';
1599    }
1600    }
1601   
 
1602  0 toggle public void writeFieldNameDirect(String text) {
1603  0 int len = text.length();
1604  0 int newcount = count + len + 3;
1605   
1606  0 if (newcount > buf.length) {
1607  0 expandCapacity(newcount);
1608    }
1609   
1610  0 int start = count + 1;
1611   
1612  0 buf[count] = '\"';
1613  0 text.getChars(0, len, buf, start);
1614   
1615  0 count = newcount;
1616  0 buf[count - 2] = '\"';
1617  0 buf[count - 1] = ':';
1618    }
1619   
 
1620  0 toggle public void write(List<String> list) {
1621  0 if (list.isEmpty()) {
1622  0 write("[]");
1623  0 return;
1624    }
1625   
1626  0 int offset = count;
1627  0 final int initOffset = offset;
1628  0 for (int i = 0, list_size = list.size(); i < list_size; ++i) {
1629  0 String text = list.get(i);
1630   
1631  0 boolean hasSpecial = false;
1632  0 if (text == null) {
1633  0 hasSpecial = true;
1634    } else {
1635  0 for (int j = 0, len = text.length(); j < len; ++j) {
1636  0 char ch = text.charAt(j);
1637  0 if (hasSpecial = (ch < ' ' //
1638    || ch > '~' //
1639    || ch == '"' //
1640    || ch == '\\')) {
1641  0 break;
1642    }
1643    }
1644    }
1645   
1646  0 if (hasSpecial) {
1647  0 count = initOffset;
1648  0 write('[');
1649  0 for (int j = 0; j < list.size(); ++j) {
1650  0 text = list.get(j);
1651  0 if (j != 0) {
1652  0 write(',');
1653    }
1654   
1655  0 if (text == null) {
1656  0 write("null");
1657    } else {
1658  0 writeStringWithDoubleQuote(text, (char) 0);
1659    }
1660    }
1661  0 write(']');
1662  0 return;
1663    }
1664   
1665  0 int newcount = offset + text.length() + 3;
1666  0 if (i == list.size() - 1) {
1667  0 newcount++;
1668    }
1669  0 if (newcount > buf.length) {
1670  0 count = offset;
1671  0 expandCapacity(newcount);
1672    }
1673   
1674  0 if (i == 0) {
1675  0 buf[offset++] = '[';
1676    } else {
1677  0 buf[offset++] = ',';
1678    }
1679  0 buf[offset++] = '"';
1680  0 text.getChars(0, text.length(), buf, offset);
1681  0 offset += text.length();
1682  0 buf[offset++] = '"';
1683    }
1684  0 buf[offset++] = ']';
1685  0 count = offset;
1686    }
1687   
1688   
 
1689  0 toggle public void writeFieldValue(char seperator, String name, char value) {
1690  0 write(seperator);
1691  0 writeFieldName(name);
1692  0 if (value == 0) {
1693  0 writeString("\u0000");
1694    } else {
1695  0 writeString(Character.toString(value));
1696    }
1697    }
1698   
 
1699  2 toggle public void writeFieldValue(char seperator, String name, boolean value) {
1700  2 if (!quoteFieldNames) {
1701  1 write(seperator);
1702  1 writeFieldName(name);
1703  1 write(value);
1704  1 return;
1705    }
1706  1 int intSize = value ? 4 : 5;
1707   
1708  1 int nameLen = name.length();
1709  1 int newcount = count + nameLen + 4 + intSize;
1710  1 if (newcount > buf.length) {
1711  1 if (writer != null) {
1712  1 write(seperator);
1713  1 writeString(name);
1714  1 write(':');
1715  1 write(value);
1716  1 return;
1717    }
1718  0 expandCapacity(newcount);
1719    }
1720   
1721  0 int start = count;
1722  0 count = newcount;
1723   
1724  0 buf[start] = seperator;
1725   
1726  0 int nameEnd = start + nameLen + 1;
1727   
1728  0 buf[start + 1] = keySeperator;
1729   
1730  0 name.getChars(0, nameLen, buf, start + 2);
1731   
1732  0 buf[nameEnd + 1] = keySeperator;
1733   
1734  0 if (value) {
1735  0 System.arraycopy(":true".toCharArray(), 0, buf, nameEnd + 2, 5);
1736    } else {
1737  0 System.arraycopy(":false".toCharArray(), 0, buf, nameEnd + 2, 6);
1738    }
1739    }
1740   
 
1741  143 toggle public void write(boolean value) {
1742  143 if (value) {
1743  78 write("true");
1744    } else {
1745  65 write("false");
1746    }
1747    }
1748   
 
1749  2114 toggle public void writeFieldValue(char seperator, String name, int value) {
1750  2114 if (value == Integer.MIN_VALUE || !quoteFieldNames) {
1751  1 write(seperator);
1752  1 writeFieldName(name);
1753  1 writeInt(value);
1754  1 return;
1755    }
1756   
1757  2113 int intSize = (value < 0) ? IOUtils.stringSize(-value) + 1 : IOUtils.stringSize(value);
1758   
1759  2113 int nameLen = name.length();
1760  2113 int newcount = count + nameLen + 4 + intSize;
1761  2113 if (newcount > buf.length) {
1762  1 if (writer != null) {
1763  1 write(seperator);
1764  1 writeFieldName(name);
1765  1 writeInt(value);
1766  1 return;
1767    }
1768  0 expandCapacity(newcount);
1769    }
1770   
1771  2112 int start = count;
1772  2112 count = newcount;
1773   
1774  2112 buf[start] = seperator;
1775   
1776  2112 int nameEnd = start + nameLen + 1;
1777   
1778  2112 buf[start + 1] = keySeperator;
1779   
1780  2112 name.getChars(0, nameLen, buf, start + 2);
1781   
1782  2112 buf[nameEnd + 1] = keySeperator;
1783  2112 buf[nameEnd + 2] = ':';
1784   
1785  2112 IOUtils.getChars(value, count, buf);
1786    }
1787   
 
1788  6 toggle public void writeFieldValue(char seperator, String name, long value) {
1789  6 if (value == Long.MIN_VALUE
1790    || !quoteFieldNames
1791    || isEnabled(SerializerFeature.BrowserCompatible.mask)
1792    ) {
1793  0 write(seperator);
1794  0 writeFieldName(name);
1795  0 writeLong(value);
1796  0 return;
1797    }
1798   
1799  6 int intSize = (value < 0) ? IOUtils.stringSize(-value) + 1 : IOUtils.stringSize(value);
1800   
1801  6 int nameLen = name.length();
1802  6 int newcount = count + nameLen + 4 + intSize;
1803  6 if (newcount > buf.length) {
1804  1 if (writer != null) {
1805  1 write(seperator);
1806  1 writeFieldName(name);
1807  1 writeLong(value);
1808  1 return;
1809    }
1810  0 expandCapacity(newcount);
1811    }
1812   
1813  5 int start = count;
1814  5 count = newcount;
1815   
1816  5 buf[start] = seperator;
1817   
1818  5 int nameEnd = start + nameLen + 1;
1819   
1820  5 buf[start + 1] = keySeperator;
1821   
1822  5 name.getChars(0, nameLen, buf, start + 2);
1823   
1824  5 buf[nameEnd + 1] = keySeperator;
1825  5 buf[nameEnd + 2] = ':';
1826   
1827  5 IOUtils.getChars(value, count, buf);
1828    }
1829   
 
1830  0 toggle public void writeFieldValue(char seperator, String name, float value) {
1831  0 write(seperator);
1832  0 writeFieldName(name);
1833  0 writeFloat(value, false);
1834    }
1835   
 
1836  1 toggle public void writeFieldValue(char seperator, String name, double value) {
1837  1 write(seperator);
1838  1 writeFieldName(name);
1839  1 writeDouble(value, false);
1840    }
1841   
 
1842  1055 toggle public void writeFieldValue(char seperator, String name, String value) {
1843  1055 if (quoteFieldNames) {
1844  1053 if (useSingleQuotes) {
1845  3 write(seperator);
1846  3 writeFieldName(name);
1847  3 if (value == null) {
1848  2 writeNull();
1849    } else {
1850  1 writeString(value);
1851    }
1852    } else {
1853  1050 if (isEnabled(SerializerFeature.BrowserCompatible)) {
1854  0 write(seperator);
1855  0 writeStringWithDoubleQuote(name, ':');
1856  0 writeStringWithDoubleQuote(value, (char) 0);
1857    } else {
1858  1050 writeFieldValueStringWithDoubleQuoteCheck(seperator, name, value);
1859    }
1860    }
1861    } else {
1862  2 write(seperator);
1863  2 writeFieldName(name);
1864  2 if (value == null) {
1865  1 writeNull();
1866    } else {
1867  1 writeString(value);
1868    }
1869    }
1870    }
1871   
 
1872  1052 toggle public void writeFieldValueStringWithDoubleQuoteCheck(char seperator, String name, String value) {
1873  1052 int nameLen = name.length();
1874  1052 int valueLen;
1875   
1876  1052 int newcount = count;
1877   
1878  1052 if (value == null) {
1879  2 valueLen = 4;
1880  2 newcount += nameLen + 8;
1881    } else {
1882  1050 valueLen = value.length();
1883  1050 newcount += nameLen + valueLen + 6;
1884    }
1885   
1886  1052 if (newcount > buf.length) {
1887  8 if (writer != null) {
1888  1 write(seperator);
1889  1 writeStringWithDoubleQuote(name, ':');
1890  1 writeStringWithDoubleQuote(value, (char) 0);
1891  1 return;
1892    }
1893  7 expandCapacity(newcount);
1894    }
1895   
1896  1051 buf[count] = seperator;
1897   
1898  1051 int nameStart = count + 2;
1899  1051 int nameEnd = nameStart + nameLen;
1900   
1901  1051 buf[count + 1] = '\"';
1902  1051 name.getChars(0, nameLen, buf, nameStart);
1903   
1904  1051 count = newcount;
1905   
1906  1051 buf[nameEnd] = '\"';
1907   
1908  1051 int index = nameEnd + 1;
1909  1051 buf[index++] = ':';
1910   
1911  1051 if (value == null) {
1912  2 buf[index++] = 'n';
1913  2 buf[index++] = 'u';
1914  2 buf[index++] = 'l';
1915  2 buf[index++] = 'l';
1916  2 return;
1917    }
1918   
1919  1049 buf[index++] = '"';
1920   
1921  1049 int valueStart = index;
1922  1049 int valueEnd = valueStart + valueLen;
1923   
1924  1049 value.getChars(0, valueLen, buf, valueStart);
1925   
1926  1049 int specialCount = 0;
1927  1049 int lastSpecialIndex = -1;
1928  1049 int firstSpecialIndex = -1;
1929  1049 char lastSpecial = '\0';
1930   
1931  18722 for (int i = valueStart; i < valueEnd; ++i) {
1932  17673 char ch = buf[i];
1933   
1934  17673 if (ch >= ']') {
1935  12987 if (ch >= 0x7F //
1936    && (ch == '\u2028' //
1937    || ch == '\u2029' //
1938    || ch < 0xA0)) {
1939  0 if (firstSpecialIndex == -1) {
1940  0 firstSpecialIndex = i;
1941    }
1942   
1943  0 specialCount++;
1944  0 lastSpecialIndex = i;
1945  0 lastSpecial = ch;
1946  0 newcount += 4;
1947    }
1948  12987 continue;
1949    }
1950   
1951  4686 boolean special = (ch < 64 && (sepcialBits & (1L << ch)) != 0) || ch == '\\';
1952  4686 if (special) {
1953  21 specialCount++;
1954  21 lastSpecialIndex = i;
1955  21 lastSpecial = ch;
1956   
1957  21 if (ch == '('
1958    || ch == ')'
1959    || ch == '<'
1960    || ch == '>'
1961    || (ch < IOUtils.specicalFlags_doubleQuotes.length //
1962    && IOUtils.specicalFlags_doubleQuotes[ch] == 4) //
1963    ) {
1964  0 newcount += 4;
1965    }
1966   
1967  21 if (firstSpecialIndex == -1) {
1968  5 firstSpecialIndex = i;
1969    }
1970    }
1971    }
1972   
1973  1049 if (specialCount > 0) {
1974  5 newcount += specialCount;
1975  5 if (newcount > buf.length) {
1976  4 expandCapacity(newcount);
1977    }
1978  5 count = newcount;
1979   
1980  5 if (specialCount == 1) {
1981  1 if (lastSpecial == '\u2028') {
1982  0 int srcPos = lastSpecialIndex + 1;
1983  0 int destPos = lastSpecialIndex + 6;
1984  0 int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
1985  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1986  0 buf[lastSpecialIndex] = '\\';
1987  0 buf[++lastSpecialIndex] = 'u';
1988  0 buf[++lastSpecialIndex] = '2';
1989  0 buf[++lastSpecialIndex] = '0';
1990  0 buf[++lastSpecialIndex] = '2';
1991  0 buf[++lastSpecialIndex] = '8';
1992  1 } else if (lastSpecial == '\u2029') {
1993  0 int srcPos = lastSpecialIndex + 1;
1994  0 int destPos = lastSpecialIndex + 6;
1995  0 int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
1996  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
1997  0 buf[lastSpecialIndex] = '\\';
1998  0 buf[++lastSpecialIndex] = 'u';
1999  0 buf[++lastSpecialIndex] = '2';
2000  0 buf[++lastSpecialIndex] = '0';
2001  0 buf[++lastSpecialIndex] = '2';
2002  0 buf[++lastSpecialIndex] = '9';
2003  1 } else if (lastSpecial == '(' || lastSpecial == ')' || lastSpecial == '<' || lastSpecial == '>') {
2004  0 final char ch = lastSpecial;
2005  0 int srcPos = lastSpecialIndex + 1;
2006  0 int destPos = lastSpecialIndex + 6;
2007  0 int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
2008  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
2009   
2010  0 int bufIndex = lastSpecialIndex;
2011  0 buf[bufIndex++] = '\\';
2012  0 buf[bufIndex++] = 'u';
2013  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
2014  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
2015  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
2016  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
2017    } else {
2018  1 final char ch = lastSpecial;
2019  1 if (ch < IOUtils.specicalFlags_doubleQuotes.length //
2020    && IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
2021  0 int srcPos = lastSpecialIndex + 1;
2022  0 int destPos = lastSpecialIndex + 6;
2023  0 int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
2024  0 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
2025   
2026  0 int bufIndex = lastSpecialIndex;
2027  0 buf[bufIndex++] = '\\';
2028  0 buf[bufIndex++] = 'u';
2029  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
2030  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
2031  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
2032  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
2033    } else {
2034  1 int srcPos = lastSpecialIndex + 1;
2035  1 int destPos = lastSpecialIndex + 2;
2036  1 int LengthOfCopy = valueEnd - lastSpecialIndex - 1;
2037  1 System.arraycopy(buf, srcPos, buf, destPos, LengthOfCopy);
2038  1 buf[lastSpecialIndex] = '\\';
2039  1 buf[++lastSpecialIndex] = replaceChars[(int) ch];
2040    }
2041    }
2042  4 } else if (specialCount > 1) {
2043  4 int textIndex = firstSpecialIndex - valueStart;
2044  4 int bufIndex = firstSpecialIndex;
2045  38 for (int i = textIndex; i < value.length(); ++i) {
2046  34 char ch = value.charAt(i);
2047   
2048  34 if (browserSecure && (ch == '('
2049    || ch == ')'
2050    || ch == '<'
2051    || ch == '>')) {
2052  0 buf[bufIndex++] = '\\';
2053  0 buf[bufIndex++] = 'u';
2054  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
2055  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8 ) & 15];
2056  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4 ) & 15];
2057  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
2058  0 valueEnd += 5;
2059  34 } else if (ch < IOUtils.specicalFlags_doubleQuotes.length //
2060    && IOUtils.specicalFlags_doubleQuotes[ch] != 0 //
2061    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
2062  20 buf[bufIndex++] = '\\';
2063  20 if (IOUtils.specicalFlags_doubleQuotes[ch] == 4) {
2064  0 buf[bufIndex++] = 'u';
2065  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
2066  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
2067  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
2068  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
2069  0 valueEnd += 5;
2070    } else {
2071  20 buf[bufIndex++] = replaceChars[(int) ch];
2072  20 valueEnd++;
2073    }
2074    } else {
2075  14 if (ch == '\u2028' || ch == '\u2029') {
2076  0 buf[bufIndex++] = '\\';
2077  0 buf[bufIndex++] = 'u';
2078  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 12) & 15];
2079  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 8) & 15];
2080  0 buf[bufIndex++] = IOUtils.DIGITS[(ch >>> 4) & 15];
2081  0 buf[bufIndex++] = IOUtils.DIGITS[ch & 15];
2082  0 valueEnd += 5;
2083    } else {
2084  14 buf[bufIndex++] = ch;
2085    }
2086    }
2087    }
2088    }
2089    }
2090   
2091   
2092  1049 buf[count - 1] = '\"';
2093    }
2094   
 
2095  0 toggle public void writeFieldValueStringWithDoubleQuote(char seperator, String name, String value) {
2096  0 int nameLen = name.length();
2097  0 int valueLen;
2098   
2099  0 int newcount = count;
2100   
2101  0 valueLen = value.length();
2102  0 newcount += nameLen + valueLen + 6;
2103   
2104  0 if (newcount > buf.length) {
2105  0 if (writer != null) {
2106  0 write(seperator);
2107  0 writeStringWithDoubleQuote(name, ':');
2108  0 writeStringWithDoubleQuote(value, (char) 0);
2109  0 return;
2110    }
2111  0 expandCapacity(newcount);
2112    }
2113   
2114  0 buf[count] = seperator;
2115   
2116  0 int nameStart = count + 2;
2117  0 int nameEnd = nameStart + nameLen;
2118   
2119  0 buf[count + 1] = '\"';
2120  0 name.getChars(0, nameLen, buf, nameStart);
2121   
2122  0 count = newcount;
2123   
2124  0 buf[nameEnd] = '\"';
2125   
2126  0 int index = nameEnd + 1;
2127  0 buf[index++] = ':';
2128  0 buf[index++] = '"';
2129   
2130  0 int valueStart = index;
2131  0 value.getChars(0, valueLen, buf, valueStart);
2132  0 buf[count - 1] = '\"';
2133    }
2134   
2135   
2136   
 
2137  3 toggle public void writeFieldValue(char seperator, String name, Enum<?> value) {
2138  3 if (value == null) {
2139  3 write(seperator);
2140  3 writeFieldName(name);
2141  3 writeNull();
2142  3 return;
2143    }
2144   
2145  0 if (writeEnumUsingName && !writeEnumUsingToString) {
2146  0 writeEnumFieldValue(seperator, name, value.name());
2147  0 } else if (writeEnumUsingToString) {
2148  0 writeEnumFieldValue(seperator, name, value.toString());
2149    } else {
2150  0 writeFieldValue(seperator, name, value.ordinal());
2151    }
2152    }
2153   
 
2154  0 toggle private void writeEnumFieldValue(char seperator, String name, String value) {
2155  0 if (useSingleQuotes) {
2156  0 writeFieldValue(seperator, name, value);
2157    } else {
2158  0 writeFieldValueStringWithDoubleQuote(seperator, name, value);
2159    }
2160    }
2161   
 
2162  2 toggle public void writeFieldValue(char seperator, String name, BigDecimal value) {
2163  2 write(seperator);
2164  2 writeFieldName(name);
2165  1 if (value == null) {
2166  1 writeNull();
2167    } else {
2168  0 int scale = value.scale();
2169  0 write(isEnabled(SerializerFeature.WriteBigDecimalAsPlain) && scale >= -100 && scale < 100
2170    ? value.toPlainString()
2171    : value.toString()
2172    );
2173    }
2174    }
2175   
 
2176  2 toggle public void writeString(String text, char seperator) {
2177  2 if (useSingleQuotes) {
2178  0 writeStringWithSingleQuote(text);
2179  0 write(seperator);
2180    } else {
2181  2 writeStringWithDoubleQuote(text, seperator);
2182    }
2183    }
2184   
 
2185  55598 toggle public void writeString(String text) {
2186  55598 if (useSingleQuotes) {
2187  38 writeStringWithSingleQuote(text);
2188    } else {
2189  55560 writeStringWithDoubleQuote(text, (char) 0);
2190    }
2191    }
2192   
 
2193  6 toggle public void writeString(char[] chars) {
2194  6 if (useSingleQuotes) {
2195  0 writeStringWithSingleQuote(chars);
2196    } else {
2197  6 String text = new String(chars);
2198  6 writeStringWithDoubleQuote(text, (char) 0);
2199    }
2200    }
2201   
 
2202  97 toggle protected void writeStringWithSingleQuote(String text) {
2203  97 if (text == null) {
2204  4 int newcount = count + 4;
2205  4 if (newcount > buf.length) {
2206  2 expandCapacity(newcount);
2207    }
2208  4 "null".getChars(0, 4, buf, count);
2209  4 count = newcount;
2210  4 return;
2211    }
2212   
2213  93 int len = text.length();
2214  93 int newcount = count + len + 2;
2215  93 if (newcount > buf.length) {
2216  15 if (writer != null) {
2217  5 write('\'');
2218  26 for (int i = 0; i < text.length(); ++i) {
2219  21 char ch = text.charAt(i);
2220  21 if (ch <= 13 || ch == '\\' || ch == '\'' //
2221    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
2222  0 write('\\');
2223  0 write(replaceChars[(int) ch]);
2224    } else {
2225  21 write(ch);
2226    }
2227    }
2228  5 write('\'');
2229  5 return;
2230    }
2231  10 expandCapacity(newcount);
2232    }
2233   
2234  88 int start = count + 1;
2235  88 int end = start + len;
2236   
2237  88 buf[count] = '\'';
2238  88 text.getChars(0, len, buf, start);
2239  88 count = newcount;
2240   
2241  88 int specialCount = 0;
2242  88 int lastSpecialIndex = -1;
2243  88 char lastSpecial = '\0';
2244  132529 for (int i = start; i < end; ++i) {
2245  132441 char ch = buf[i];
2246  132441 if (ch <= 13 || ch == '\\' || ch == '\'' //
2247    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
2248  63 specialCount++;
2249  63 lastSpecialIndex = i;
2250  63 lastSpecial = ch;
2251    }
2252    }
2253   
2254  88 newcount += specialCount;
2255  88 if (newcount > buf.length) {
2256  4 expandCapacity(newcount);
2257    }
2258  88 count = newcount;
2259   
2260  88 if (specialCount == 1) {
2261  4 System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, end - lastSpecialIndex - 1);
2262  4 buf[lastSpecialIndex] = '\\';
2263  4 buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial];
2264  84 } else if (specialCount > 1) {
2265  7 System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, end - lastSpecialIndex - 1);
2266  7 buf[lastSpecialIndex] = '\\';
2267  7 buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial];
2268  7 end++;
2269  243 for (int i = lastSpecialIndex - 2; i >= start; --i) {
2270  236 char ch = buf[i];
2271   
2272  236 if (ch <= 13 || ch == '\\' || ch == '\'' //
2273    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
2274  52 System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1);
2275  52 buf[i] = '\\';
2276  52 buf[i + 1] = replaceChars[(int) ch];
2277  52 end++;
2278    }
2279    }
2280    }
2281   
2282  88 buf[count - 1] = '\'';
2283    }
2284   
 
2285  0 toggle protected void writeStringWithSingleQuote(char[] chars) {
2286  0 if (chars == null) {
2287  0 int newcount = count + 4;
2288  0 if (newcount > buf.length) {
2289  0 expandCapacity(newcount);
2290    }
2291  0 "null".getChars(0, 4, buf, count);
2292  0 count = newcount;
2293  0 return;
2294    }
2295   
2296  0 int len = chars.length;
2297  0 int newcount = count + len + 2;
2298  0 if (newcount > buf.length) {
2299  0 if (writer != null) {
2300  0 write('\'');
2301  0 for (int i = 0; i < chars.length; ++i) {
2302  0 char ch = chars[i];
2303  0 if (ch <= 13 || ch == '\\' || ch == '\'' //
2304    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
2305  0 write('\\');
2306  0 write(replaceChars[(int) ch]);
2307    } else {
2308  0 write(ch);
2309    }
2310    }
2311  0 write('\'');
2312  0 return;
2313    }
2314  0 expandCapacity(newcount);
2315    }
2316   
2317  0 int start = count + 1;
2318  0 int end = start + len;
2319   
2320  0 buf[count] = '\'';
2321    // text.getChars(0, len, buf, start);
2322  0 System.arraycopy(chars, 0, buf, start, chars.length);
2323  0 count = newcount;
2324   
2325  0 int specialCount = 0;
2326  0 int lastSpecialIndex = -1;
2327  0 char lastSpecial = '\0';
2328  0 for (int i = start; i < end; ++i) {
2329  0 char ch = buf[i];
2330  0 if (ch <= 13 || ch == '\\' || ch == '\'' //
2331    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
2332  0 specialCount++;
2333  0 lastSpecialIndex = i;
2334  0 lastSpecial = ch;
2335    }
2336    }
2337   
2338  0 newcount += specialCount;
2339  0 if (newcount > buf.length) {
2340  0 expandCapacity(newcount);
2341    }
2342  0 count = newcount;
2343   
2344  0 if (specialCount == 1) {
2345  0 System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, end - lastSpecialIndex - 1);
2346  0 buf[lastSpecialIndex] = '\\';
2347  0 buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial];
2348  0 } else if (specialCount > 1) {
2349  0 System.arraycopy(buf, lastSpecialIndex + 1, buf, lastSpecialIndex + 2, end - lastSpecialIndex - 1);
2350  0 buf[lastSpecialIndex] = '\\';
2351  0 buf[++lastSpecialIndex] = replaceChars[(int) lastSpecial];
2352  0 end++;
2353  0 for (int i = lastSpecialIndex - 2; i >= start; --i) {
2354  0 char ch = buf[i];
2355   
2356  0 if (ch <= 13 || ch == '\\' || ch == '\'' //
2357    || (ch == '/' && isEnabled(SerializerFeature.WriteSlashAsSpecial))) {
2358  0 System.arraycopy(buf, i + 1, buf, i + 2, end - i - 1);
2359  0 buf[i] = '\\';
2360  0 buf[i + 1] = replaceChars[(int) ch];
2361  0 end++;
2362    }
2363    }
2364    }
2365   
2366  0 buf[count - 1] = '\'';
2367    }
2368   
 
2369  646 toggle public void writeFieldName(String key) {
2370  646 writeFieldName(key, false);
2371    }
2372   
 
2373  4012331 toggle public void writeFieldName(String key, boolean checkSpecial) {
2374  4012331 if (key == null) {
2375  0 write("null:");
2376  0 return;
2377    }
2378   
2379  4012331 if (useSingleQuotes) {
2380  44 if (quoteFieldNames) {
2381  32 writeStringWithSingleQuote(key);
2382  32 write(':');
2383    } else {
2384  12 writeKeyWithSingleQuoteIfHasSpecial(key);
2385    }
2386    } else {
2387  4012287 if (quoteFieldNames) {
2388  4012267 writeStringWithDoubleQuote(key, ':');
2389    } else {
2390  20 boolean hashSpecial = key.length() == 0;
2391  89 for (int i = 0; i < key.length(); ++i) {
2392  75 char ch = key.charAt(i);
2393  75 boolean special = (ch < 64 && (sepcialBits & (1L << ch)) != 0) || ch == '\\';
2394  75 if (special) {
2395  6 hashSpecial = true;
2396  6 break;
2397    }
2398    }
2399  20 if (hashSpecial) {
2400  9 writeStringWithDoubleQuote(key, ':');
2401    } else {
2402  11 write(key);
2403  11 write(':');
2404    }
2405    }
2406    }
2407    }
2408   
 
2409  12 toggle private void writeKeyWithSingleQuoteIfHasSpecial(String text) {
2410  12 final byte[] specicalFlags_singleQuotes = IOUtils.specicalFlags_singleQuotes;
2411   
2412  12 int len = text.length();
2413  12 int newcount = count + len + 1;
2414  12 if (newcount > buf.length) {
2415  5 if (writer != null) {
2416  3 if (len == 0) {
2417  1 write('\'');
2418  1 write('\'');
2419  1 write(':');
2420  1 return;
2421    }
2422   
2423  2 boolean hasSpecial = false;
2424  6 for (int i = 0; i < len; ++i) {
2425  5 char ch = text.charAt(i);
2426  5 if (ch < specicalFlags_singleQuotes.length && specicalFlags_singleQuotes[ch] != 0) {
2427  1 hasSpecial = true;
2428  1 break;
2429    }
2430    }
2431   
2432  2 if (hasSpecial) {
2433  1 write('\'');
2434    }
2435  7 for (int i = 0; i < len; ++i) {
2436  5 char ch = text.charAt(i);
2437  5 if (ch < specicalFlags_singleQuotes.length && specicalFlags_singleQuotes[ch] != 0) {
2438  1 write('\\');
2439  1 write(replaceChars[(int) ch]);
2440    } else {
2441  4 write(ch);
2442    }
2443    }
2444  2 if (hasSpecial) {
2445  1 write('\'');
2446    }
2447  2 write(':');
2448  2 return;
2449    }
2450   
2451  2 expandCapacity(newcount);
2452    }
2453   
2454  9 if (len == 0) {
2455  2 int newCount = count + 3;
2456  2 if (newCount > buf.length) {
2457  1 expandCapacity(count + 3);
2458    }
2459  2 buf[count++] = '\'';
2460  2 buf[count++] = '\'';
2461  2 buf[count++] = ':';
2462  2 return;
2463    }
2464   
2465  7 int start = count;
2466  7 int end = start + len;
2467   
2468  7 text.getChars(0, len, buf, start);
2469  7 count = newcount;
2470   
2471  7 boolean hasSpecial = false;
2472   
2473  1066 for (int i = start; i < end; ++i) {
2474  1059 char ch = buf[i];
2475  1059 if (ch < specicalFlags_singleQuotes.length && specicalFlags_singleQuotes[ch] != 0) {
2476  14 if (!hasSpecial) {
2477  7 newcount += 3;
2478  7 if (newcount > buf.length) {
2479  2 expandCapacity(newcount);
2480    }
2481  7 count = newcount;
2482   
2483  7 System.arraycopy(buf, i + 1, buf, i + 3, end - i - 1);
2484  7 System.arraycopy(buf, 0, buf, 1, i);
2485  7 buf[start] = '\'';
2486  7 buf[++i] = '\\';
2487  7 buf[++i] = replaceChars[(int) ch];
2488  7 end += 2;
2489  7 buf[count - 2] = '\'';
2490   
2491  7 hasSpecial = true;
2492    } else {
2493  7 newcount++;
2494  7 if (newcount > buf.length) {
2495  1 expandCapacity(newcount);
2496    }
2497  7 count = newcount;
2498   
2499  7 System.arraycopy(buf, i + 1, buf, i + 2, end - i);
2500  7 buf[i] = '\\';
2501  7 buf[++i] = replaceChars[(int) ch];
2502  7 end++;
2503    }
2504    }
2505    }
2506   
2507  7 buf[newcount - 1] = ':';
2508    }
2509   
 
2510  13882 toggle public void flush() {
2511  13882 if (writer == null) {
2512  1 return;
2513    }
2514   
2515  13881 try {
2516  13881 writer.write(buf, 0, count);
2517  13880 writer.flush();
2518    } catch (IOException e) {
2519  1 throw new JSONException(e.getMessage(), e);
2520    }
2521  13880 count = 0;
2522    }
2523   
2524   
2525    }